package cn.xd.base.domain.entity;

import cn.hutool.crypto.SecureUtil;
import cn.xd.base.basic.type.*;
import cn.xd.base.domain.bean.command.AddAdminUserCommand;
import cn.xd.base.domain.bean.command.UpdateAdminUserCommand;
import cn.xd.base.domain.bean.command.common.ChangeStatusCommand;
import cn.xd.core.basic.common.CreatorId;
import cn.xd.core.basic.common.UpdateTime;
import cn.xd.core.basic.common.UpdaterId;
import cn.xd.common.enums.common.CommonStatusEnum;
import cn.xd.core.ddd.entity.Aggregate;
import lombok.Data;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Data
public class AdminUser implements Aggregate<AdminUserId> {
    private AdminUserId id;
    private AdminUserAccount account;
    private AdminUserPwd pwd;
    private GlobalUserId globalUserId;
    private AdminUserName name;
    private AdminUserGender gender;
    private AdminUserAvatarUrl avatarUrl;
    private AdminUserStatus status;
    private CreatorId creatorId;
    private cn.xd.core.basic.common.CreateTime createTime;
    private UpdaterId updaterId;
    private UpdateTime updateTime;

    private List<AdminUserOrgRole> orgRoles;

    /**
     * 新增用户
     *
     * @param command
     * @param userId
     * @return
     */
    public static AdminUser add(AddAdminUserCommand command, Long userId) {
        AdminUser adminUser = new AdminUser();
        adminUser.setAccount(AdminUserAccount.of(command.getAccount()));
        //BCrypt加密,默认密码123456
        adminUser.setPwd(AdminUserPwd.of(SecureUtil.md5("123456")));
        adminUser.setGlobalUserId(GlobalUserId.of(command.getGlobalUserId()));
        adminUser.setName(AdminUserName.of(command.getName()));
        adminUser.setGender(AdminUserGender.of(command.getGender()));
        adminUser.setAvatarUrl(AdminUserAvatarUrl.of(command.getAvatarUrl()));
        adminUser.setStatus(AdminUserStatus.of(command.getStatus()));

        adminUser.setCreatorId(CreatorId.of(userId));
        adminUser.setCreateTime(cn.xd.core.basic.common.CreateTime.now());
        adminUser.setUpdaterId(UpdaterId.of(userId));
        adminUser.setUpdateTime(UpdateTime.now());


        adminUser.orgRoles = command.getOrgRoles().stream().map(item -> AdminUserOrgRole.builder().orgRoleId(AdminOrgRoleId.of(item)).createTime(cn.xd.core.basic.common.CreateTime.now()).creatorId(CreatorId.of(userId)).build()).toList();
        return adminUser;
    }

    /**
     * 更新用户信息
     *
     * @param command
     * @param userId
     */
    public void update(UpdateAdminUserCommand command, List<AdminUserOrgRole> adminUserOrgRoles, List<AdminUserOrgRole> completeAdminUserOrgRole, Long userId) {
        this.setGlobalUserId(GlobalUserId.of(command.getGlobalUserId()));
        this.setName(AdminUserName.of(command.getName()));
        this.setAccount(AdminUserAccount.of(command.getAccount()));
        this.setGender(AdminUserGender.of(command.getGender()));
        this.setAvatarUrl(AdminUserAvatarUrl.of(command.getAvatarUrl()));
        this.setStatus(AdminUserStatus.of(command.getStatus()));
        this.setUpdaterId(UpdaterId.of(userId));
        this.setUpdateTime(UpdateTime.now());
        Map<Long, AdminUserOrgRole> maps = new HashMap<>();
        List<Long> orgRoleIds = new ArrayList<>();
        for (AdminUserOrgRole adminOrgRole : adminUserOrgRoles) {
            orgRoleIds.add(adminOrgRole.getOrgRoleId().getValue());
            maps.put(adminOrgRole.getOrgRoleId().getValue(), adminOrgRole);
        }
        List<AdminUserOrgRole> adminUserOrgRoleList = new ArrayList<>(command.getOrgRoles().stream().map(item -> {
            if (orgRoleIds.contains(item)) {
                return maps.get(item);
            }
            return AdminUserOrgRole.builder().userId(AdminUserId.of(command.getId())).orgRoleId(AdminOrgRoleId.of(item)).createTime(cn.xd.core.basic.common.CreateTime.now()).creatorId(CreatorId.of(userId)).build();
        }).toList());
        adminUserOrgRoleList.addAll(completeAdminUserOrgRole);
        this.setOrgRoles(adminUserOrgRoleList);
    }

    /**
     * 修改密码
     *
     * @param pwd
     * @param userId
     */
    public void changePwd(String pwd, Long userId) {
        //BCrypt加密,默认密码123456
        this.setPwd(AdminUserPwd.of(SecureUtil.md5(pwd)));
        this.setUpdaterId(UpdaterId.of(userId));
        this.setUpdateTime(UpdateTime.now());
    }

    /**
     * 修改状态
     *
     * @param command
     * @param userId
     */
    public void changeStatus(ChangeStatusCommand command, Long userId) {
        this.setStatus(AdminUserStatus.of(command.getStatus()));
        this.setUpdaterId(UpdaterId.of(userId));
        this.setUpdateTime(UpdateTime.now());
    }

    /**
     * 删除用户
     */
    public void delete() {
        this.setStatus(AdminUserStatus.of(CommonStatusEnum.DELETED.getCode()));
    }
}
